home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 2 / ETO Development Tools 2.iso / Tools - Objects / MacApp / MacApp CD Release / MacApp 2.0.1 (Many Libraries) / Libraries / UPatch.inc1.p < prev    next >
Encoding:
Text File  |  1990-10-25  |  6.8 KB  |  274 lines  |  [TEXT/MPS ]

  1. {$P}
  2. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
  3. { UPatch.inc1.p }
  4. { Copyright © 1985-1990 by Apple Computer, Inc.  All rights reserved. }
  5.  
  6. TYPE
  7.     { System heap block record for PatchTrap }
  8.     PTBlockPtr            = ^PTBlock;
  9.     PTBlock             = RECORD
  10.         Jmp:                INTEGER;
  11.         Routine:            Ptr;
  12.         END;
  13.  
  14.     { System heap block record for HeadPatch }
  15.     TPBlockPtr            = ^TPBlock;
  16.     TPBlock             = RECORD
  17.         MoveL:                INTEGER;
  18.         OldTrapAddr:        LONGINT;
  19.         Jmp:                INTEGER;
  20.         Routine:            Ptr;
  21.         END;
  22.  
  23.     { System heap block record for Head1Patch }
  24.     T1PBlockPtr         = ^T1PBlock;
  25.     T1PBlock            = RECORD
  26.         MoveParameter:        LONGINT;
  27.         MoveL:                INTEGER;
  28.         OldTrapAddr:        LONGINT;
  29.         Jmp:                INTEGER;
  30.         Routine:            Ptr;
  31.         END;
  32.  
  33. FUNCTION NewPermPtr(logicalSize: Size): Ptr;            { So we don't have to USE UMemory }
  34.     EXTERNAL;
  35.  
  36. {--------------------------------------------------------------------------------------------------}
  37. {$S MAMiniInit}
  38.  
  39. PROCEDURE InitUPatch;
  40.  
  41.     BEGIN
  42.     pPatchList := NIL;                                    { Initialize the linked list of patches. }
  43.     END;
  44.  
  45. {--------------------------------------------------------------------------------------------------}
  46. {$S MAPatchRes}
  47.  
  48. FUNCTION AllocBlock(blockSize: INTEGER;
  49.                     theTrapNum: INTEGER;
  50.                     VAR thePatch: TrapPatch): Ptr;
  51.  
  52.  { If blockSize is greater than zero, AllocBlock allocates a non-
  53.   relocatable block in the system heap, of size blockSize.    It then
  54.   fills all fields of thePatch.  If blockSize is zero, then no block
  55.   is allocated and AllocBlock fills fields of thePatch. }
  56.  
  57.     VAR
  58.         theBlock:            Ptr;
  59.  
  60.     BEGIN
  61.     IF blockSize > 0 THEN
  62.         BEGIN
  63.         IF qNeedsROM128K | gConfiguration.hasROM128K THEN
  64.             theBlock := NewPermPtr(blockSize)
  65.         ELSE
  66.             theBlock := NewPtrSys(blockSize);
  67.         END
  68.     ELSE
  69.         theBlock := NIL;
  70.  
  71.     WITH thePatch DO                                    { get thePatch in a register for speed }
  72.         BEGIN
  73.         jmpPtr := theBlock;
  74.         OldTrapAddr := NGetTrapAddress(theTrapNum, GetTrapType(theTrapNum));
  75.         trapNum := theTrapNum;
  76.         nextPatch := pPatchList;
  77.         END;
  78.     pPatchList := @thePatch;
  79.     AllocBlock := theBlock;
  80.     END;
  81.  
  82. {--------------------------------------------------------------------------------------------------}
  83. {$S MAPatchRes}
  84.  
  85. FUNCTION PatchTrap(VAR thePatch: TrapPatch;
  86.                    theTrapNum: INTEGER;
  87.                    theRoutine: Ptr): OSErr;
  88.  
  89.     VAR
  90.         patchBlock:         PTBlockPtr;
  91.  
  92.     BEGIN
  93.     IF qNeedsROM128K | gConfiguration.hasROM128K THEN
  94.         BEGIN
  95.         { On 128K ROMs, setup the patch record and the trap address }
  96.         patchBlock := PTBlockPtr(AllocBlock(0, theTrapNum, thePatch));
  97.         NSetTrapAddress(ORD4(theRoutine), theTrapNum, GetTrapType(theTrapNum));
  98.         PatchTrap := noErr;
  99.         END
  100.     ELSE
  101.         BEGIN
  102.  
  103.         { Allocate the system heap block, and fill thePatch }
  104.         patchBlock := PTBlockPtr(AllocBlock(SIZEOF(PTBlock), theTrapNum, thePatch));
  105.  
  106.         IF patchBlock <> NIL THEN
  107.             BEGIN
  108.             { Stuff the code into the block }
  109.             WITH patchBlock^ DO
  110.                 BEGIN
  111.                 Jmp := $4EF9;                            { JMP #Routine }
  112.                 Routine := theRoutine;
  113.                 END;
  114.  
  115.             { Set the trap address to the block of code in the system heap }
  116.             NSetTrapAddress(ORD4(patchBlock), theTrapNum, GetTrapType(theTrapNum));
  117.             END;
  118.  
  119.         PatchTrap := MemError;
  120.         END;
  121.     END;
  122.  
  123. {--------------------------------------------------------------------------------------------------}
  124. {$S MAPatchRes}
  125.  
  126. FUNCTION HeadPatch(VAR thePatch: TrapPatch;
  127.                    theTrapNum: INTEGER;
  128.                    theRoutine: Ptr): OSErr;
  129.  
  130.     VAR
  131.         patchBlock:         TPBlockPtr;
  132.  
  133.     BEGIN
  134.     { Allocate the system heap block, and fill thePatch }
  135.     patchBlock := TPBlockPtr(AllocBlock(SIZEOF(TPBlock), theTrapNum, thePatch));
  136.  
  137.     IF patchBlock <> NIL THEN
  138.         BEGIN
  139.         { Stuff the code into the block }
  140.         WITH patchBlock^ DO
  141.             BEGIN
  142.             MoveL := $2F3C;                             { MOVE.L #OldTrapAddr,-(SP) }
  143.             OldTrapAddr := thePatch.OldTrapAddr;
  144.             Jmp := $4EF9;                                { JMP #Routine }
  145.             Routine := theRoutine;
  146.             END;
  147.  
  148.         { Set the trap address to the block of code in the system heap }
  149.         NSetTrapAddress(ORD4(patchBlock), theTrapNum, GetTrapType(theTrapNum));
  150.         END;
  151.     HeadPatch := MemError;
  152.     END;
  153.  
  154. {--------------------------------------------------------------------------------------------------}
  155. {$S MAPatchRes}
  156.  
  157. FUNCTION Head1Patch(VAR thePatch: TrapPatch;
  158.                     theTrapNum: INTEGER;
  159.                     theRoutine: Ptr): OSErr;
  160.  
  161.     VAR
  162.         patchBlock:         T1PBlockPtr;
  163.  
  164.     BEGIN
  165.     { Allocate the system heap block, and fill thePatch }
  166.     patchBlock := T1PBlockPtr(AllocBlock(SIZEOF(T1PBlock), theTrapNum, thePatch));
  167.  
  168.     IF patchBlock <> NIL THEN
  169.         BEGIN
  170.         { Stuff the code into the block }
  171.         WITH patchBlock^ DO
  172.             BEGIN
  173.             MoveParameter := $2F2F0004;                 { MOVE.L 4(SP),-(SP) }
  174.             MoveL := $2F3C;                             { MOVE.L #OldTrapAddr,-(SP) }
  175.             OldTrapAddr := thePatch.OldTrapAddr;
  176.             Jmp := $4EF9;                                { JMP #Routine }
  177.             Routine := theRoutine;
  178.             END;
  179.  
  180.         { Set the trap address to the block of code in the system heap }
  181.         NSetTrapAddress(ORD4(patchBlock), theTrapNum, GetTrapType(theTrapNum));
  182.         END;
  183.     Head1Patch := MemError;
  184.     END;
  185.  
  186. {--------------------------------------------------------------------------------------------------}
  187. {$S MAPatchRes}
  188.  
  189. PROCEDURE UnpatchTrap(VAR thePatch: TrapPatch);
  190.  
  191.     VAR
  192.         aPatch:             TrapPatchPtr;
  193.  
  194.     BEGIN
  195.     { Unlink the patch from the linked list of patches }
  196.     IF @thePatch = pPatchList THEN
  197.         pPatchList := thePatch.nextPatch
  198.     ELSE
  199.         BEGIN
  200.         aPatch := pPatchList;
  201.         WHILE aPatch^.nextPatch <> @thePatch DO
  202.             BEGIN
  203.             aPatch := aPatch^.nextPatch;
  204.             IF aPatch = NIL THEN
  205.             { Couldn't find thePatch, so don't try to unpatch it. }
  206.                 EXIT(UnpatchTrap);
  207.             END;
  208.         aPatch^.nextPatch := thePatch.nextPatch;
  209.         END;
  210.  
  211.     WITH thePatch DO
  212.         BEGIN
  213.         { If the patch allocated a block in the system heap, deallocate it }
  214.         jmpPtr := DisposeIfPtr(jmpPtr);
  215.  
  216.         { Restore the trap address }
  217.         NSetTrapAddress(OldTrapAddr, trapNum, GetTrapType(trapNum));
  218.         END;
  219.  
  220.     END;
  221.  
  222. {--------------------------------------------------------------------------------------------------}
  223. {$S MAPatchRes}
  224.  
  225. PROCEDURE UnpatchAll;
  226.  
  227.     BEGIN
  228.     WHILE pPatchList <> NIL DO
  229.         UnpatchTrap(pPatchList^);
  230.     END;
  231.  
  232. {--------------------------------------------------------------------------------------------------}
  233. {$S MAPatchRes}
  234.  
  235. PROCEDURE EachPatchDo(FUNCTION DoToPatch(thePatchPtr: TrapPatchPtr): BOOLEAN);
  236.  
  237.     VAR
  238.         aPatchPtr:    TrapPatchPtr;
  239.  
  240.     BEGIN
  241.     aPatchPtr := pPatchList;
  242.  
  243.     WHILE aPatchPtr <> NIL DO
  244.         IF NOT DoToPatch(aPatchPtr) THEN
  245.             aPatchPtr := aPatchPtr^.nextPatch
  246.         ELSE
  247.             LEAVE;
  248.     END;
  249.  
  250. {--------------------------------------------------------------------------------------------------}
  251. {$S MAPatchRes}
  252.  
  253. PROCEDURE SetCallBack(targProc: ProcPtr; itsRefCon: Longint; theCallBackPtr: CallBackPtr);
  254.  
  255. {
  256. 00000000: 2F17             '/.'               MOVE.L      (A7),-(A7)    ; move old rtn address
  257. 00000002: 2F7C 1122 3344 '/|."3D'           MOVE.L      #$11223344,$0004(A7)    ; plop refcon in
  258.              0004
  259. 0000000A: 4EF9 1122 3344 'N.."3D'           JMP          $11223344     ; shove off
  260. }
  261.  
  262.     BEGIN
  263.     WITH theCallBackPtr^ DO
  264.         BEGIN
  265.         saveRtnAdd := $2F17;
  266.         moveRefCon := $2F7C;
  267.         refCon := itsRefCon;
  268.         targOffset := $0004;
  269.         jmpInst := $4EF9;
  270.         jmpTarg := ORD(targProc);
  271.         END;
  272.         { ??? should we flush the processor cache at this point? }
  273.     END;
  274.